/**=========================================================
 * Service: simple-ui-grid.js
 =========================================================*/
App.service('SimpleUiGrid', ['$timeout', '$translate', 'HttpUtils','Utils','toaster', 
    function($timeout, $translate, httpUtils, utils, toaster) {
        'use strict';
        
        return {
            init: function($scope, options) {
                var defaultOptions = {
                    /**
                     * 表格配置绑定的变量名
                     */
                    optionModel: 'gridOptions',
                    /**
                     * 分页配置绑定的变量名
                     */
                    pageOptionModel: 'pageOptionModel',
                    /**
                     * 后台排序配置绑定的变量名
                     */
                    sortOptionModel: 'sortOptionModel',
                    /**
                     * 表格Api绑定的变量名
                     */
                    gridApi: 'gridApi',
                    /**
                     * 自定义查询
                     * 如果是通用查询 无需配置
                     */
                    url: '',
                    /**
                     * 是否分页
                     */
                    needPage: true,
                    /**
                     * 初始分页大小
                     */
                    pageSize: null,
                    /**
                     * 分页类型 
                     * common：正常分页
                     * date：日期分页
                     */
                    pageType: 'date',
                    /**
                     * 是否需要导出
                     */
                    needExport: true, 
                    /**
                     * 是否多选
                     */
                    multiSelect: false,
                    /**
                     * 是否显示列尾
                     */
                    showColumnFooter: false,
                    /**
                     * 当列信息从后台取时 指定列尾的聚合类型
                     */
                    footerAggregationType: null,
                    /**
                     * 自动选中第一行
                     */
                    autoSelect: false,
                    /**
                     * 是否后台排序
                     */
                    remoteSort: false,
                    /**
                     * 是否表格树
                     */
                    expandable: false,
                    /**
                     * 当列信息从后台取时 可以在前端进行增加头列
                     */
                    headColumns: [],
                    /**
                     * 表格列
                     */
                    columns: [
                        //解决树模式下动态列头导致的列头高度无法自适应的问题
                        {
                            displayName: '',
                            field: 'keep_column_head_height_in_tree_view'
                        }
                    ],
                    /**
                     * 当列信息从后台取时 可以在前端进行增加尾列
                     */
                    footColumns: [],
                    /**
                     * 是否显示指标列
                     */
                    showMetricColumn: true,
                    /**
                     * 增加行合计列
                     */
                    needRowTotal: false,
                    /**
                     * 增加行趋势
                     */
                    needRowSparkLine: false,
                    /**
                     * 菜单配置
                     */
                    menus: [],
                    /**
                     * 行高
                     */
                    rowHeight: 30,
                    /**
                     * 自定义行模版
                     */
                    rowTemplate: null,
                    /**
                     * 控制器中的查询方法 用于切换页时查询
                     */
                    controllerSearchFn: options.controllerSearchFn,
                    /**
                     * 注册事件方法
                     */
                    registerApiFn: options.registerApiFn,
                    /**
                     * 数据加载完成后触发
                     */
                    afterDataLoadEvent: options.afterDataLoadEvent,
                    /**
                     * 双击事件触发调用的方法名
                     */
                    rowDoubleClickEventName: options.rowDoubleClickEventName
                };
                
                var finalOptions = angular.extend(defaultOptions,options);

                $scope[finalOptions.optionModel] = {
                    enableRowSelection: true,
                    enableRowHeaderSelection: false,
                    multiSelect: finalOptions.multiSelect,
                    modifierKeysToMultiSelect: true,
                    showTreeExpandNoChildren: true,
                    enableExpandAll: false,
                    noUnselect: true,
                    enableHorizontalScrollbar: true,
                    rowHeight: finalOptions.rowHeight,
                    enableColumnMenus: false,
                    columnDefs: finalOptions.columns,
                    showColumnFooter: finalOptions.showColumnFooter,
                    flatEntityAccess: true,
                    onRegisterApi: function(gridApi) {
                        $scope[finalOptions.gridApi] = gridApi;
                        //排序
                        if(finalOptions.remoteSort){
                            gridApi.core.on.sortChanged($scope, function(grid, sortColumns) {
                                $scope[finalOptions.pageOptionModel].sort = sortColumns;
                                finalOptions.controllerSearchFn.call();
                            });
                        }
                        //分页
                        if(finalOptions.needPage){
                            gridApi.pagination.on.paginationChanged($scope, function (newPage, pageSize) {
                                $scope[finalOptions.pageOptionModel].page = newPage;
                                $scope[finalOptions.pageOptionModel].pageSize = pageSize;
                                finalOptions.controllerSearchFn.call();
                            });
                        }
                        //自定义
                        if (!utils.isEmpty(finalOptions.registerApiFn)){
                            finalOptions.registerApiFn.call(this,gridApi);
                        }
                    }
                };
                
                //自定义模版
                if(!utils.isEmpty(finalOptions.rowTemplate)) {
                    $scope[finalOptions.optionModel].rowTemplate = finalOptions.rowTemplate;
                }else if (finalOptions.rowDoubleClickEventName){
                    //需要双击行事件
                    var fnName = 'grid.appScope.' + finalOptions.rowDoubleClickEventName + '(row,col)'
                    $scope[finalOptions.optionModel].rowTemplate =
                        "<div ng-dblclick='" + fnName + "' ng-repeat=\"(colRenderIndex, col) in colContainer.renderedColumns track by col.uid\" \
                              ui-grid-one-bind-id-grid=\"rowRenderIndex + '-' + col.uid + '-cell'\" \
                              class=\"ui-grid-cell\" ng-class=\"{ 'ui-grid-row-header-cell': col.isRowHeader }\" \
                              role=\"{{col.isRowHeader ? 'rowheader' : 'gridcell'}}\" ui-grid-cell> \
                        </div>"
                }
                
                //排序
                if(finalOptions.remoteSort) {
                    $scope[finalOptions.optionModel].useExternalSorting = true;
                }
                
                //分页
                if(finalOptions.needPage){
                    var pageSize = finalOptions.pageSize;
                    if (utils.isEmpty(pageSize)){
                        pageSize = finalOptions.pageType == 'date' ? 7 : 10;
                    }
                    $scope[finalOptions.pageOptionModel] = {
                        page: 1,
                        pageSize: pageSize,
                        sort: []
                    };
                    
                    $scope[finalOptions.optionModel].paginationPageSizes = [10, 25, 50, 100];
                    $scope[finalOptions.optionModel].paginationPageSize = pageSize;
                    $scope[finalOptions.optionModel].useExternalPagination = true;
                    
                    //分页类型
                    if (finalOptions.pageType == 'date'){
                        $scope[finalOptions.optionModel].paginationTemplate = 'ui-grid/datePagination';
                        $scope[finalOptions.optionModel].paginationPageSizes = [7];
                    }
                }     
                
                //导出
                if (finalOptions.needExport){
                    $scope[finalOptions.optionModel].enableGridMenu = true;
                    $scope[finalOptions.optionModel].gridMenuShowHideColumns = false;
                    $scope[finalOptions.optionModel].gridMenuCustomItems = [
                        {
                            title: $translate.instant('button.EXPORT'),
                            action: function ($event) {
                                //text|dataIndex|width
                                var options = this.grid.options,
                                    fileName = utils.dateFormat(new Date(),'yyyyMMddhhmmss') + '.xlsx',
                                    url = utils.getBackendPath('/common/exportToExcel') + '?filename=' + fileName
                                
                                url += '&vType=export';

                                if (!utils.isEmpty(options.queryParams)){
                                    for (var paramName in options.queryParams){
                                        if (options.queryParams[paramName] != undefined && paramName != 'vType'){
                                            url += '&' + paramName + '=' + options.queryParams[paramName];
                                        }
                                    }
                                }
                                var columnInfos = '';
                                if (finalOptions.pageType == 'date'){
                                    for (var i = 0; i < finalOptions.headColumns.length; i++){
                                        if (finalOptions.headColumns[i].field != 'widgets' && !((finalOptions.headColumns[i].visible + '') == 'false')){
                                            columnInfos += finalOptions.headColumns[i].displayName + '|' + finalOptions.headColumns[i].field + '|100,';
                                        }
                                    }
                                    columnInfos += $translate.instant('metric') + '|metric_name|100,';
                                }else{
                                    for (var i = 0; i < options.columnDefs.length; i++){
                                        if (options.columnDefs[i].field != 'widgets' && !((options.columnDefs[i].visible + '') == 'false')){
                                            columnInfos += options.columnDefs[i].displayName + '|' + options.columnDefs[i].field + '|100,';
                                        }
                                    }
                                }

                                var form = document.createElement('form');
                                form.setAttribute('style','display:none');  
                                form.setAttribute('target','');  
                                form.setAttribute('method','post');
                                form.setAttribute('action',url);
                                
                                var input = document.createElement("input");  
                                input.type = "text";  
                                input.name = "column";  
                                input.value = escape(columnInfos);
                                
                                form.appendChild(input);
                                
                                document.body.appendChild(form);
                                
                                form.submit();
                                form.remove();
                            }
                        }
                    ]
                }
                
                //表格菜单
                if (finalOptions.menus.length > 0){
                    $scope[finalOptions.optionModel].enableGridMenu = true;
                    $scope[finalOptions.optionModel].gridMenuShowHideColumns = false;
                    if (utils.isEmpty($scope[finalOptions.optionModel].gridMenuCustomItems)){
                        $scope[finalOptions.optionModel].gridMenuCustomItems = finalOptions.menus;
                    }else{
                        $scope[finalOptions.optionModel].gridMenuCustomItems = utils.mergeArray($scope[finalOptions.optionModel].gridMenuCustomItems, finalOptions.menus);
                    }
                }
                            
                return {
                    scope: $scope,
                    options: finalOptions,
                    /**
                     * 更新表格数据
                     */
                    draw: function(params){                        
                        var scope = this.scope;
                        var options = this.options;
                        
                        scope[options.optionModel].status = 'loading';

                        if (utils.isEmpty(params)){
                            params = scope[options.optionModel].queryParams;
                        }else{
                            scope[options.optionModel].queryParams = params;
                        }
                        params.vType = 'grid';
                        
                        scope[options.optionModel].data = [];
                        if (options.columns.length == 0){
                            scope[options.optionModel].columnDefs = [];
                        }
                        
                        var url = options.url;
                        
                        if (utils.isEmpty(url)){
                            url = options.needPage ? utils.getQueryPageUrl() : utils.getQueryListUrl();
                        }
                        
                        if(options.needPage){               
                            params.page = scope[options.pageOptionModel].page;
                            params.pageSize = scope[options.pageOptionModel].pageSize;
                        }
                        
                        if(options.remoteSort){
                            if (scope[options.pageOptionModel].sort.length > 0){
                                params.sort = scope[options.pageOptionModel].sort[0].field;
                                params.sortDirection = scope[options.pageOptionModel].sort[0].sort.direction;
                            }else{
                                params.sort = null;
                                params.sortDirection = null;
                            }
                        }
                        
                        httpUtils.get(url,params,
                            function (result) {
                                if (!utils.isEmpty(result.datas.gridColumns)){
                                    //后台定义列信息
                                    var columns = result.datas.gridColumns;
                                    
                                    if (!options.showMetricColumn){
                                        //隐藏指标列
                                        columns = columns.slice(1,columns.length);
                                    }
                                    if (options.headColumns.length > 0){
                                        columns = utils.mergeArray(options.headColumns,columns);
                                    }
                                    if (options.footColumns.length > 0){
                                        columns = utils.mergeArray(columns,options.footColumns);
                                    }
                                    
                                    if (options.needRowTotal){
                                        columns.push({
                                            displayName: $translate.instant('total'),
                                            field: 'total',
                                            cellFilter: "numberFormat",
                                            headerCellClass: "align-right",
                                            cellClass: "align-right",
                                            cellTemplate: '\
                                                <div class="ui-grid-cell-contents" >\
                                                    <span style="font-weight: bold">{{COL_FIELD CUSTOM_FILTERS}}</span>\
                                                </div>\
                                            '
                                        })
                                    }

                                    if (options.needRowSparkLine){
                                        columns.push({
                                            displayName: '',
                                            field: 'sparkline',
                                            cellTemplate: '\
                                                <div style="text-align:center;margin-top: 5px">\
                                                    <sparkline data-type="bar" data-bar-color="#5d9cec" data-height="20" data-bar-width="3" \
                                                        data-bar-spacing="2" values="{{COL_FIELD}}" data-resize="true"></sparkline>\
                                                </div>\
                                            '
                                        })
                                    }

                                    for (var i = 0; i < columns.length; i++){
                                        columns[i].cellTooltip = function(row, col) {
                                            return row.entity.metric_tips;
                                        }
                                        
                                        if (columns[i].field == "metric_name"){
                                            columns[i].displayName = $translate.instant('metric');
                                        }

                                        if (!utils.isEmpty(options.footerAggregationType) && utils.isTimeStr(columns[i].field)){
                                            columns[i].aggregationType = options.footerAggregationType;
                                            columns[i].footerCellClass = columns[i].cellClass;
                                            columns[i].footerCellFilter = columns[i].cellFilter;
                                        }
                                    }
                                    
                                    scope[options.optionModel].columnDefs = columns;
                                }
                                
                                if (options.needRowTotal || options.needRowSparkLine){
                                    var dates = [];
                                    for (var k = 0; k < columns.length; k++){
                                        if (utils.isDateString(columns[k].field)){
                                            dates.push(columns[k].field);
                                        }
                                    }

                                    for (var i = 0; i < result.datas.gridDatas.length; i++){
                                        var total = 0,datas = [];
                                        for (var j = 0; j < dates.length; j++){
                                            total += parseInt(result.datas.gridDatas[i][dates[j]]);
                                            datas.push(result.datas.gridDatas[i][dates[j]]);
                                        }
                                        result.datas.gridDatas[i].sparkline = datas.join(',');
                                        result.datas.gridDatas[i].total = total
                                    }
                                }

                                if (options.expandable){
                                    for (var i = 0; i < result.datas.gridDatas.length; i++){
                                        result.datas.gridDatas[i].$$treeLevel = 0;
                                        result.datas.gridDatas[i].$$childrenLoaded = false;                                        
                                    }
                                }
                                
                                scope[options.optionModel].data = result.datas.gridDatas;
                                scope[options.optionModel].totalItems = result.totalCount;
                                
                                if (options.autoSelect){
                                    $timeout(function(){
                                        scope[options.gridApi].selection.selectRowByVisibleIndex(0);
                                    },0)
                                }
                                
                                if (options.afterDataLoadEvent instanceof Function){
                                    options.afterDataLoadEvent.call(this,scope[options.optionModel].data,scope[options.optionModel].columnDefs);
                                }

                                scope[options.optionModel].status = 'succeed';
                            },
                            function(data,header,config,status){
                                scope[options.optionModel].status = 'fail';
                                // toaster.pop('error', '', '数据获取失败 请重试');
                            }
                        );
                    },
                    /**
                     * 获取所有数据
                     */
                    getAll: function(){
                        var scope = this.scope;
                        var options = this.options;
                        
                        return scope[options.optionModel].data;
                    },
                    /**
                     * 获取行数
                     */
                    getCount: function(){
                        var scope = this.scope;
                        var options = this.options;
                        
                        return scope[options.optionModel].data.length;
                    },
                    /**
                     * 获取选中行
                     */
                    getSelection: function(){
                        var scope = this.scope;
                        var options = this.options;
                        
                        return scope[options.gridApi].selection.getSelectedRows();
                    },
                    /**
                     * 获取行的位置
                     */
                    getIndex: function(data){
                        var scope = this.scope;
                        var options = this.options;
                        
                        var allDatas = scope[options.optionModel].data;
                        for (var i = 0; i < allDatas.length; i++){
                            if (data.$$hashKey === allDatas[i].$$hashKey){
                                return i;
                            }
                        }
                    },
                    /**
                     * 获取行
                     */
                    getRowByIndex: function(index){
                        var scope = this.scope;
                        var options = this.options;
                        
                        return scope[options.optionModel].data[index];
                    },
                    /**
                     * 清空表格数据
                     */
                    clear: function(){
                        var scope = this.scope;
                        var options = this.options;
                        
                        scope[options.optionModel].data = [];
                        scope[options.optionModel].totalItems = 0;
                    },
                    /**
                     * 增加一行
                     */
                    addRow: function(data,index){
                        var scope = this.scope;
                        var options = this.options;
                        
                        if (utils.isEmpty(index)){
                            scope[options.optionModel].data.push(data);
                        }else{
                            scope[options.optionModel].data.splice(index, 0, data);
                        }
                    },
                    /**
                     * 删除一行
                     */
                    deleteRow: function(data){
                        var scope = this.scope;
                        var options = this.options;
                        
                        var datas = scope[options.optionModel].data;
                        utils.removeFromArray(datas,data,'$$hashKey');
                    },
                     /**
                     * 通过位置删除行
                     */
                    deleteRowByIndex: function(index,length){
                        var scope = this.scope;
                        var options = this.options;
                        
                        var datas = scope[options.optionModel].data;
                        datas.splice(index, utils.coalesce(length,1));
                    },
                    /**
                     * 选中指定行
                     */
                    selectRow: function(index){
                        var scope = this.scope;
                        var options = this.options;
                        
                        scope[options.gridApi].selection.selectRowByVisibleIndex(index);
                    },
                    /**
                     * 选中最后一行
                     */
                    selectLastRow: function(){
                        var scope = this.scope;
                        scope[options.gridApi].selection.selectRowByVisibleIndex([scope[options.gridApi].grid.rows.length - 1]);
                    },
                    /**
                     * 跳转到指定页数
                     */
                    goToPage: function(page){
                        var scope = this.scope;
                        var options = this.options;
                        
                        if ($scope[options.pageOptionModel].page == page){
                            options.controllerSearchFn.call();
                        }else{
                            scope[options.gridApi].pagination.seek(page);
                        }   
                    },
                    /**
                     * 展开行
                     */
                    expandRow: function(row){
                        var scope = this.scope;
                        var options = this.options;
                        
                        return scope[options.gridApi].treeBase.expandRow(row);
                    },
                    getGridOptions: function(){
                        var scope = this.scope;
                        var options = this.options;

                        return scope[options.optionModel];
                    }
                }   
            }
        }
    }
]);
